//! TitanEventManager.js
//! version : 1.0
//! authors : 周成功
//! import $$E from '../TitanEventManager';
//! last date : 2021-07-15

// 记录各个事件执行状态
// 目的：事件出错重新执行，共执行三次，如果连续三次失败，界面提示：通讯失败，请断开通讯线并退出本应该，重新打开再试。
// 失败条件：1)超时2秒无响应; 2)回调方法无返回或返回false
// 成功条件：回调方法返回true
/** 使用方法
$$E.initEnv(socket);   // 初始化
$$E.register("comList", function(data) {   // 注册事件，并执行事件回调方法
        if(!$$8.isDefined(data)) {
            return false;   // 重新调用事件触发，三次连续失败，弹窗报错，终止事件
        }
        return true;        // 终止事件调用
    });
$$E.call('comList');        // 触发事件
*/

import moment from "moment";
import config from "./config";
import $$8 from "./TitanV81";

const TitanEventManager = {
    // 结构 {'事件名'：{retry:'执行次数', last:'最后时间', args:'调用参数'}}
    __db : {}
    ,getManager : function(){
        return window["$$8_EventManager"];
    }
    ,getSocket : function(){
        return window["$$8_Socket"];
    }
    ,getEvent : function(name) {
        return this.getManager()[name];
    }
    ,initEnv : function(socket, comName) {
        window["$$8_EventManager"] = {};
        if($$8.isDefined(socket)) {
            window["$$8_Socket"] = socket;
        }
        if($$8.isEmpty(comName)==false) {
            window["$$8_Com"] = decodeURIComponent(comName);
        }
        this.checkEvent();
    }
    , register : function(name, callback) {
        this.getManager()[name] = {retry:0, last:(new Date()).getTime(), args:{}};
        this.getSocket()
            .off(name)
            .on(name, data => {
                let obj = this.getEvent(name);
                let ret = callback(data, obj.args);
                if(!$$8.isDefined(ret) || ret===false) {
                    this.call(name, obj.args);
                }
            });
    }
    , registerOnline : function(name, okCallback, errorCallback) {
        this.getManager()[name] = {retry:0, last:(new Date()).getTime(), args:{}};
        this.getSocket()
            .off(name)
            .on(name, data => {
                let obj = this.getEvent(name);
                let ret = $$E.__callbackOnline(data, okCallback, errorCallback, obj.args);
                if(!$$8.isDefined(ret) || ret===false) {
                    this.call(name, obj.args);
                }
            });
    }
    , __callbackOnline : function(data, okCallback, errorCallback, args) {
        let funcOK = okCallback || function(response,args) {};
        let funcError = errorCallback || function(response,args) {};
        if (data === "err") {
            funcError(data,args);
            setTimeout(function(){window.alert("设备拒绝访问,请检查设备连接!");}, 1);
            return true;
        }
        $$8.action("S1701M1001A04", {
            length: data.length,
            bytes: data
        }, function(res){
            if(!$$8.isDefined(res)) {
                return;
            }
            funcOK(res, args);
        }, function(message){
            funcError(message,args);
            window.alert(message);
        });
        return true;
    }
    , __callback : function(data) {
    }
    , callOnline : function(name,args) {
        if(name==="jueyuanId4") {
            $$8.action("S1701M1001A03", {
                cmd: "CMDA8"
            }, function(res){
                let hex = res.row;
                if(!$$8.isDefined(hex)) {
                    return;
                }
                let _args = args || {};
                _args.hex = hex;
                $$E.call('jueyuanId4', _args);
            }, function(message){
                window.alert(message);
            });
        } else {
            window.alert("callEvent：未识别的事件名称="+name);
        }
    }
    , call : function(name, args) {
        let _args = args || {};
        _args.comName = window["$$8_Com"];
        if(name==="comList") {
        } else if(name==="jueyuanId4") {
            /* _args.hex = args; */
        } else if(name==="clearDevice") {
            _args.hex = config.order["insulation"].clear_data;
        } else if(name==="jueyuanReadData") {
            /*
            _args.hex = config.order["insulation"].get_data.replace(/{NUM}/, args);
            $$8.log("jueyuanReadData"
                , "get_data", config.order["insulation"].get_data
                , "args", args
                , "hex", _args.hex
                );
            */
        /*
        } else if(name==="") {
        } else {
            _args = args || {};
        */
        }

        let obj = this.getEvent(name);
        if(obj.retry>=3) {
            obj.retry = 0;
            //$$8.log(name+".error", "obj", obj);
            window.alert("通讯失败["+name+"]，请重连通讯线并重启动本助手。");
        } else {
            obj.retry = obj.retry + 1;
            obj.last = (new Date()).getTime();
            obj.args = _args;
            //$$8.log(`[${moment().format('HH:mm:ss')}] ${name}.request.${obj.retry}`, "obj", obj);
            this.getSocket().emit(name, obj.args);
        }
    }
    , checkEvent : function() {
        try{
            let manager = window["$$8_EventManager"];
            let socket = window["$$8_Socket"];
            Object.keys(manager).forEach(function(key){
                let obj = manager[key];
                if(obj) {
                   if(obj.retry===0) {
                       return;
                   }
                   if(obj.retry>=4) {
                       return;
                   }
                } else {
                   return;
                }
                let curr = (new Date()).getTime();
                if(obj && (curr-obj.last)>=2000) {
                   window["$$E"].call(key, obj.args);
                }
            });
        } catch(e) {
            $$8.log("$$E.checkEvent", e);
        } finally {
            setTimeout(window["$$E"].checkEvent, 1000);
        }
    }
};
window["$$E"] = TitanEventManager;
export default TitanEventManager;